//
//  MyWebView.m
//  sudic
//
//  Created by linqc on 17/4/8.
//  Copyright © 2017年 linqc. All rights reserved.
//

#import "MyWebView.h"
#import "Common.h"
#import "DictPageViewPlugin.h"
#import <Flutter/FlutterCodecs.h>

@interface CustomURLSchemeHandler : NSObject <WKURLSchemeHandler>
@property(nonatomic) MyWebView* webview;
@end

@implementation CustomURLSchemeHandler {
    NSMutableSet* _schemeTask;
}

//这里拦截到URLScheme为customScheme的请求后，根据自己的需求,返回结果，并返回给WKWebView显示
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask{
    NSURLRequest *request = urlSchemeTask.request;
    NSLog(@"request = %@",request);

    NSString* versionNum = [[UIDevice currentDevice] systemVersion];
    if ([versionNum containsString:@"13."]) {
        SEL selector = sel_registerName("_setLoadResourcesSerially:");
        id webViewClass = NSClassFromString(@"WebView");
        if ([webViewClass respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
            [webViewClass performSelector:selector withObject:@NO];
#pragma clang diagnostic pop
        }
    }

    if (!_schemeTask) {
        _schemeTask = [[NSMutableSet alloc] init];
    }



    NSString* url = urlSchemeTask.request.URL.absoluteString;
    FlutterMethodChannel* channel = [DictPageViewPlugin getChannel];
    if (channel) {
        NSDictionary* args = @{
                @"id": [NSNumber numberWithInt:self.webview.platformViewId],
                @"tabIndex": [NSNumber numberWithInt:self.webview.tabIndex],
                @"url": url
        };
        __weak __typeof__(self) weakSelf = self;
        [channel invokeMethod:@"shouldInterceptRequest" arguments:[Common objectToJson:args] result:^(id  _Nullable result){
            FlutterStandardTypedData* flutterData = result;
            NSData* data = result ? flutterData.data : nil;
            NSLog(@"....shouldInterceptRequest ret:%@", data ? @"has data" : @"null");
            if (data) {
                @try {
                    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:nil expectedContentLength:data.length textEncodingName:nil];
                    [urlSchemeTask didReceiveResponse:response];
                    [urlSchemeTask didReceiveData:data];
                    [urlSchemeTask didFinish];
                } @catch (NSException* ex) {
                    NSLog(@"..exception:%@", ex);
                } @finally {

                }
            } else {
                NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    if (error) {
                        [urlSchemeTask didFailWithError:error];
                    } else {
                        @try {
                            [urlSchemeTask didReceiveResponse:response];
                            [urlSchemeTask didReceiveData:data];
                            [urlSchemeTask didFinish];
                        } @catch (NSException* ex) {

                        } @finally {

                        }
                    }

                }];
                [task resume];
            }
        }];
        return;
    }


    //如果是返回本地资源的话
//    UIImage *image = [UIImage imageNamed:@"yang.jpg"];
//    NSData *data = UIImageJPEGRepresentation(image, 1.0);
//    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:@"image/jpeg" expectedContentLength:data.length textEncodingName:nil];
//    [urlSchemeTask didReceiveResponse:response];
//    [urlSchemeTask didReceiveData:data];
//    [urlSchemeTask didFinish];
}

- (void)webView:(WKWebView *)webVie stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask {
    NSLog(@"stop = %@",urlSchemeTask);

}

-(void)sendRequestWithUrlSchemeTask:
        (id <WKURLSchemeTask>)urlSchemeTask
                           mimeType:(NSString*)mimeType
                        requestData:(NSData*)requestData {
    NSData* data = requestData ? requestData : [NSData data];
    NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:urlSchemeTask.request.URL statusCode:200 HTTPVersion:nil headerFields:nil];
    @try {
        [urlSchemeTask didReceiveResponse:response];
        [urlSchemeTask didReceiveData:data];
        [urlSchemeTask didFinish];
    } @catch (NSException* ex) {

    } @finally {

    }
}

@end


@interface MyWebView ()<WKNavigationDelegate, WKScriptMessageHandler, UIGestureRecognizerDelegate>
@end

@implementation MyWebView {
    TMyWkJsCallback cb_;
}

-(void)setPlatformViewId:(int64_t)viewId andTabIndex:(int)index {
    self.platformViewId = viewId;
    self.tabIndex = index;
}


+(void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method originalMethod1 = class_getClassMethod(self, @selector(handlesURLScheme:));
        Method originalMethod2 = class_getClassMethod(self, @selector(handlesMyURLScheme:));
        method_exchangeImplementations(originalMethod1, originalMethod2);
    });
}

+ (BOOL)handlesMyURLScheme:(NSString *)urlScheme {
    if ([urlScheme isEqualToString:@"https"] ||
        [urlScheme isEqualToString:@"http"] ||
        [urlScheme isEqualToString:@"file"]) {
        return NO;
    }

    return [self handlesMyURLScheme:urlScheme];
}


-(instancetype)initWithFrame:(CGRect)frame {
    CustomURLSchemeHandler *handler = [CustomURLSchemeHandler new];
    WKWebViewConfiguration* cfg =[[WKWebViewConfiguration alloc] init];
    [cfg setURLSchemeHandler:handler forURLScheme:@"https"];
    [cfg setURLSchemeHandler:handler forURLScheme:@"http"];
    [cfg setURLSchemeHandler:handler forURLScheme:@"file"];


    self = [super initWithFrame:frame configuration:cfg];
    handler.webview = self;

    [self setWebPopMenu];
    
    self.navigationDelegate = self;
    return self;
}


-(void)setWebPopMenu {
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    UIMenuItem *menuItem0 = [[UIMenuItem alloc] initWithTitle:@"拷貝" action:@selector(onWebViewMenuCopy:)];
    UIMenuItem *menuItem1 = [[UIMenuItem alloc] initWithTitle:@"搜尋" action:@selector(onWebViewFind:)];
    UIMenuItem *menuItem2 = [[UIMenuItem alloc] initWithTitle:@"全選" action:@selector(onWebViewSelectAll:)];
    
    NSArray *array = [NSArray arrayWithObjects:menuItem0, menuItem2, menuItem1,nil];
    [menuController setMenuItems:array];
}

- (IBAction)onWebViewMenuCopy:(id)sender
{
    [self copy:sender];
}

- (IBAction)onWebViewSelectAll:(id)sender {
    [self selectAll:sender];
}

- (IBAction)onWebViewFind:(id)sender
{
    __weak __typeof__(self) weakSelf = self;
    [self evaluateJavaScript:@"window.getSelection().toString()" completionHandler:^(id _Nullable info, NSError * _Nullable error) {
        NSString* selection = info;
        if (selection != nil && selection.length > 0) {
            FlutterMethodChannel* channel = [DictPageViewPlugin getChannel];
            if (channel) {
                NSDictionary* args = @{
                        @"id": [NSNumber numberWithInt:weakSelf.platformViewId],
                        @"tabIndex": [NSNumber numberWithInt:weakSelf.tabIndex],
                        @"word": selection
                };
                [channel invokeMethod:@"search" arguments:[Common objectToJson:args]];
            }
        }
    }];
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (
        action == @selector(onWebViewMenuCopy:)||
        action == @selector(onWebViewFind:) ||
        action == @selector(onWebViewSelectAll:))
        
    {
        return YES;
    }
    return  NO;
}



#pragma wknavigationDelegate
// <5>页面加载完成时使用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    if (self.delegateLink) {
        if ([self.delegateLink respondsToSelector:@selector(webView:didFinishNavigation:)])
        {
            [self.delegateLink webView:webView didFinishNavigation:navigation];
        }
    }
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
    if (self.delegateLink) {
        if ([self.delegateLink respondsToSelector:@selector(webView:didStartProvisionalNavigation:)])
        {
            [self.delegateLink webView:webView didStartProvisionalNavigation:navigation];
        }
    }
}


// <3>在收到响应是，决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    BOOL hasCalledLink = NO;
    if (self.delegateLink) {
        if ([self.delegateLink respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)])
        {
            [self.delegateLink webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
            
            hasCalledLink = YES;
        }
    }
    
    if (!hasCalledLink) {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}


// <4>内容开始返回时使用
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
    if (self.delegateLink) {
        if ([self.delegateLink respondsToSelector:@selector(webView:didCommitNavigation:)])
        {
            [self.delegateLink webView:webView didCommitNavigation:navigation];
        }
    }
}


// <6>页面加载失败时使用
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    if (self.delegateLink) {
        if ([self.delegateLink respondsToSelector:@selector(webView:didFailNavigation:withError:)])
       {
           [self.delegateLink webView:webView didFailNavigation:navigation withError:error];
       }
   }
}


// <7>接收到服务器跳转请求的时候调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
    if (self.delegateLink) {
         if ([self.delegateLink respondsToSelector:@selector(webView:didReceiveServerRedirectForProvisionalNavigation:)])
        {
            [self.delegateLink webView:webView didReceiveServerRedirectForProvisionalNavigation:navigation];
        }
    }
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    BOOL hasCalledLink = NO;
    if (self.delegateLink) {
        if ([self.delegateLink respondsToSelector:@selector(webView:decidePolicyForNavigationResponse:decisionHandler:)])
        {
            [self.delegateLink webView:webView decidePolicyForNavigationResponse:navigationResponse decisionHandler:decisionHandler];
            hasCalledLink = YES;
        }
    }

    if (!hasCalledLink) {
        decisionHandler(WKNavigationResponsePolicyAllow);
    }
}

@end
